﻿#region License

// PentaBiz - Sustainable Software Development Framework Copyright (C) 2013 Zoltán Csizmazia
// 
// This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

#endregion

using System.Linq;
using PentaBiz.Cloud.CloudDb.EntityModel.SystemModel;

namespace PentaBiz.Cloud.CloudDb.Migrations.BuiltInMigrations
{
    /// <summary>
    ///     Migrate the default system scope to the database
    /// </summary>
    public class SystemScopeMigrationStep : IMigrationStep
    {
        private readonly string _password;
        private readonly string _roleName;
        private readonly string _scopeName;
        private readonly string _userName;

        /// <summary>
        ///     Initializes a new instance of the <see cref="SystemScopeMigrationStep" /> class.
        /// </summary>
        /// <param name="scopeName">Name of the scope.</param>
        /// <param name="roleName">Name of the role.</param>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        public SystemScopeMigrationStep(string scopeName = SystemScope.RootScopeName,
                                        string roleName = SystemRole.RootRoleName,
                                        string userName = SystemUser.RootServiceUserName,
                                        string password = "secret")
        {
            _scopeName = scopeName;
            _roleName = roleName;
            _userName = userName;
            _password = password;
        }


        /// <summary>
        ///     Gets the name of the scope.
        /// </summary>
        /// <value>
        ///     The name of the scope.
        /// </value>
        public string ScopeName
        {
            get { return _scopeName; }
        }

        /// <summary>
        ///     Gets the name of the role.
        /// </summary>
        /// <value>
        ///     The name of the role.
        /// </value>
        public string RoleName
        {
            get { return _roleName; }
        }

        /// <summary>
        ///     Gets the name of the user.
        /// </summary>
        /// <value>
        ///     The name of the user.
        /// </value>
        public string UserName
        {
            get { return _userName; }
        }

        /// <summary>
        ///     Gets the password.
        /// </summary>
        /// <value>
        ///     The password.
        /// </value>
        public string Password
        {
            get { return _password; }
        }

        #region IMigrationStep Members

        /// <summary>
        ///     Executes this migration step instance.
        /// </summary>
        /// <typeparam name="TContext">The type of the context.</typeparam>
        /// <param name="context">The context.</param>
        public void Execute<TContext>(TContext context) where TContext : ScopedDbContext<TContext>
        {
            if (context.SystemScopes.Any(ss => ss.Name == ScopeName) == false)
            {
                SystemScope scope = context.SystemScopes.Create();
                scope.Name = ScopeName;

                SystemRole role = context.SystemRoles.Create();
                role.RoleName = RoleName;
                role.SystemScope = scope;

                SystemUser user = context.SystemUsers.Create();
                user.UserName = UserName;
                user.IsServiceUser = true;
                user.CreatePassword(Password);
                user.SystemRoles.Add(role);
                user.SystemScope = scope;

                context.SystemScopes.Add(scope);
                context.SystemRoles.Add(role);
                context.SystemUsers.Add(user);

                context.SaveChanges();
            }
        }

        #endregion
    }
}